package com.xiaoyu.lanling.feature.im.request.flow

import android.text.TextUtils
import com.xiaoyu.base.utils.upload.UploadImageOriginalType
import com.xiaoyu.base.utils.upload.UploadListener
import com.xiaoyu.base.utils.upload.UploadMediaType
import com.xiaoyu.im.datamodel.MessageStatus
import com.xiaoyu.im.request.MessageRequest
import com.xiaoyu.im.request.flow.BasePrepareAction
import com.xiaoyu.im.request.flow.RequestFlow
import com.xiaoyu.lanling.common.Constant.MessageAttrsKey.FIRST_PICTURE
import com.xiaoyu.lanling.common.Constant.MessageAttrsKey.LOCAL_FIRST_PICTURE
import com.xiaoyu.lanling.feature.chat.model.message.MessageType.TYPE_1001_IMAGE
import com.xiaoyu.lanling.feature.chat.model.message.MessageType.TYPE_1002_AUDIO
import com.xiaoyu.lanling.feature.chat.model.message.MessageType.TYPE_1005_VIDEO
import com.xiaoyu.lanling.feature.im.data.IMData

class PrepareAction : BasePrepareAction() {

    override fun onPrepare(request: MessageRequest) {
        val messageType = request.pendingMessage.payload.messageType

        when (messageType) {
            TYPE_1001_IMAGE -> prepareMediaResource(request, UploadMediaType.IMAGE)
            TYPE_1002_AUDIO -> prepareMediaResource(request, UploadMediaType.AUDIO);
            TYPE_1005_VIDEO -> prepareVideoResource(request, UploadMediaType.VIDEO)
            else -> updateRequestStatus(true, request)
        }
    }

    private fun prepareVideoResource(request: MessageRequest, mediaType: String) {
        val remoteUrl = request.pendingMessage.payload.url
        val hasUploaded = prepared(remoteUrl)
        if (hasUploaded) {
            updateRequestStatus(true, request)
        } else {
            val videoFilePath = request.pendingMessage.payload.filePath
            IMData.uploadResourceAsync(request.chatId, mediaType, videoFilePath, UploadImageOriginalType.ORIGINAL, object : UploadListener() {
                override fun onSuccess(url: String) {
                    request.pendingMessage.setFileRemoteUrl(url)
                    uploadVideoFirstPicture(request)
                }

                override fun onFailure(exception: Exception) {
                    updateRequestStatus(false, request)
                }
            })
        }
    }

    private fun uploadVideoFirstPicture(request: MessageRequest) {
        val firstPicture = request.pendingMessage.payload.attrsCopy.optString(LOCAL_FIRST_PICTURE)
        IMData.uploadResourceAsync(request.chatId, UploadMediaType.IMAGE, firstPicture, UploadImageOriginalType.ORIGINAL, object : UploadListener() {
            override fun onSuccess(url: String) {
                request.pendingMessage.payload.putAttrs(FIRST_PICTURE, url)
                updateRequestStatus(true, request)
            }

            override fun onFailure(exception: Exception) {
            }
        })
    }

    private fun prepareMediaResource(request: MessageRequest, mediaType: String) {
        val remoteUrl = request.pendingMessage.payload.url
        val hasUploaded = prepared(remoteUrl)
        if (hasUploaded) {
            updateRequestStatus(true, request)
        } else {
            val filePath = request.pendingMessage.payload.filePath
            IMData.uploadResourceAsync(request.chatId, mediaType, filePath, UploadImageOriginalType.COMPRESSED, object : UploadListener() {
                override fun onSuccess(url: String) {
                    request.pendingMessage.setFileRemoteUrl(url)
                    val prepared = prepared(url)
                    updateRequestStatus(prepared, request)
                }
            });
        }
    }

    private fun prepared(url: String?): Boolean {
        return !TextUtils.isEmpty(url)
    }

    private fun updateRequestStatus(prepareSuccess: Boolean, request: MessageRequest) {
        if (prepareSuccess) {
            request.status = MessageStatus.PREPARED
        } else {
            request.status = MessageStatus.UPLOAD_RESOURCE_FAILED
        }
        RequestFlow.evolveToNextStatus(request)
    }

    private fun replaceOriginFile(request: MessageRequest, path: String) {
        request.pendingMessage.payload.filePath = path
    }
}